using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace AutoTLBB {
    public class ProcessMemoryReader :IDisposable {
        private IntPtr m_handleProcess = IntPtr.Zero;
        private Process m_readingProcess = null;
        /// <summary>
        /// Closes the handle.
        /// </summary>
        public void CloseHandle() {
            try {
                ReadMemory.CloseHandle(this.m_handleProcess);
            } catch {
                throw new Exception("CloseHandle failed");
            }
        }
        /// <summary>
        /// Opens the process.
        /// </summary>
        public void OpenProcess() {
            this.m_handleProcess = ReadMemory.OpenProcess(ReadMemory.PROCESS_VM_READ, 1, (uint)this.ReadingProcess.Id);
        }
        /// <summary>
        /// Reads the offset.
        /// </summary>
        /// <param name="dwAddress">The dw address.</param>
        /// <param name="offset">The offset.</param>
        /// <returns></returns>
        public byte[] ReadOffset(uint dwAddress, uint offset) {
            byte[] lpBuffer = new byte[15];
            uint num = dwAddress + offset;
            ReadMemory.ReadProcessMemory(this.m_handleProcess, (IntPtr)num, lpBuffer, lpBuffer.Length, 0);
            return lpBuffer;
        }
        /// <summary>
        /// Gets or sets the reading process.
        /// </summary>
        /// <value>
        /// The reading process.
        /// </value>
        public Process ReadingProcess {
            get {
                return this.m_readingProcess;
            }
        }
        public ProcessMemoryReader(int id) {
            this.m_readingProcess = ProcessCacheProvider.GetProcess(id);
            OpenProcess();
        }
        #region IDisposable Members

        public void Dispose() {
            try {
                ReadMemory.CloseHandle(this.m_handleProcess);
            } catch {
                throw new Exception("CloseHandle failed");
            }
        }

        #endregion
    }
    public class ProcessCacheProvider {
        private static Dictionary<int, Process> s_cache = new Dictionary<int,Process>();
        private ProcessCacheProvider() {
        }
        public static Process GetProcess(int id) {
            Process p =null;
            if (!s_cache.TryGetValue(id, out p)) {
                p= Process.GetProcessById(id);
                s_cache.Add(id, p);
            }
            return p;
        }
    }
}

